use crate::convert_option_field;

use super::super::entities::address_book::ActiveModel;
use sea_orm::ActiveValue;
use serde::{Deserialize, Serialize};
use utoipa::{IntoParams, ToSchema};

#[derive(Debug, ToSchema, Deserialize, Serialize, IntoParams)]
#[serde(rename_all = "camelCase")]
pub struct AddressDTO {
    pub city_code: Option<String>,
    pub city_name: Option<String>,
    pub consignee: Option<String>,
    pub detail: Option<String>,
    pub district_code: Option<String>,
    pub district_name: Option<String>,
    pub is_default: Option<i8>,
    pub label: Option<String>,
    pub phone: Option<String>,
    pub province_code: Option<String>,
    pub province_name: Option<String>,
    pub sex: Option<String>,
    pub user_id: Option<i64>,
}

impl From<AddressDTO> for ActiveModel {
    fn from(dto: AddressDTO) -> Self {
        ActiveModel {
            consignee: convert_option_field!(dto, consignee, not_set),
            sex: convert_option_field!(dto, sex, not_set),
            province_code: convert_option_field!(dto, province_code, not_set),
            province_name: convert_option_field!(dto, province_name, not_set),
            city_code: convert_option_field!(dto, city_code, not_set),
            city_name: convert_option_field!(dto, city_name, not_set),
            district_code: convert_option_field!(dto, district_code, not_set),
            district_name: convert_option_field!(dto, district_name, not_set),
            detail: convert_option_field!(dto, detail, not_set),
            label: convert_option_field!(dto, label, not_set),
            phone: dto
                .phone
                .map_or(ActiveValue::not_set(), |code| ActiveValue::set(code)),
            is_default: dto
                .is_default
                .map_or(ActiveValue::not_set(), |code| ActiveValue::set(code)),
            ..Default::default()
        }
    }
}

#[derive(Serialize, Deserialize)]
pub struct SetDefaultDTO {
    pub id: i64,
}

impl From<SetDefaultDTO> for ActiveModel {
    fn from(value: SetDefaultDTO) -> Self {
        Self {
            id: ActiveValue::set(value.id),
            ..Default::default()
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct SearchDTO {
    pub user_id: i64,
    pub is_default: bool,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct DeleteById {
    pub id: i64,
}
